package com.vercon.moensmart.fragment

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageInstaller
import android.content.pm.PackageManager
import android.os.Handler
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.vercon.common.Constants
import com.vercon.common.R
import com.vercon.common.room.entry.AppDataRoomInfo
import com.vercon.common.utils.APPUtil
import com.vercon.common.utils.LogUtils
import com.vercon.common.utils.MirrorDataStorage
import com.vercon.common.utils.ThreadUtil
import com.vercon.common.view.pagerecyclerview.PagerGridLayoutManager
import com.vercon.common.view.pagerecyclerview.PagerGridSnapHelper
import com.vercon.moensmart.MainApplication
import com.vercon.moensmart.adapter.AppAdapter
import com.vercon.moensmart.adapter.IndicatorAdapter
import com.vercon.moensmart.adapter.base.BaseAdapter
import com.vercon.moensmart.databinding.FragmentAppBinding
import com.vercon.moensmart.dialog.DeleteDialog
import com.vercon.moensmart.event.AppDeleteEvent
import com.vercon.moensmart.event.InstalledEvent
import com.vercon.moensmart.fragment.base.BaseFragment
import com.vercon.moensmart.fragment.manager.FragmentOpenManager
import com.vercon.moensmart.fragment.setting.WiFiFragment
import com.vercon.moensmart.mode.AppMode
import com.vercon.moensmart.utils.AppUtil
import com.vercon.moensmart.utils.DefaultMenuUtil
import com.vercon.moensmart.utils.ToastUtils
import com.vercon.moensmart.viewmodel.SystemViewModel
import io.reactivex.Completable
import io.reactivex.MaybeObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.Optional

class AppFragment : BaseFragment<FragmentAppBinding>(), BaseAdapter.BaseItemListener<AppMode>,
    AppAdapter.OnItemDeleteListener, PagerGridLayoutManager.PageListener {
    private val TAG = javaClass.simpleName
    var appRecycler: RecyclerView? = null
    var ll_delete_ing: LinearLayout? = null
    var pointRecycler: RecyclerView? = null
    private var mAppModes: ArrayList<AppMode>? = null
    private var mAppAdapter: AppAdapter? = null
    private var scrollX = 0f
    private var scrollY = 0f
    private var mDeleteAppMode: AppMode? = null
    private var mHashMap: HashMap<String, AppMode>? = null

    //    public static boolean isAppFragmentShow = false;
    private val mHandler = Handler()
    private var time = 0
    private var mPackageName = ""
    private val rows = 3
    private val columns = 4
    private val isFirst = true
    private var mLayoutManager: PagerGridLayoutManager? = null
    private var mPointAdapter: IndicatorAdapter? = null
    var systemViewModel : SystemViewModel? = null
    private var index = 0
    override fun onCreateViewBinding(inflater: LayoutInflater, parent: ViewGroup?): FragmentAppBinding {
        return FragmentAppBinding.inflate(inflater, parent, false)
    }

    override fun initData() {
        pointRecycler = binding?.pointRecycler
        ll_delete_ing = binding?.llDeleteIng
        appRecycler = binding?.appRecycler
        mAppModes = ArrayList<AppMode>()
        systemViewModel = ViewModelProvider(requireActivity())[SystemViewModel::class.java]

        //tv_weather.setText(String.format("N%s -", WeatherUtils.getUnit()));
        mPointAdapter = IndicatorAdapter(activity)
        mAppAdapter = activity?.let { AppAdapter(it) }
        // 1.分页布局管理器
        mLayoutManager = PagerGridLayoutManager(rows, columns, PagerGridLayoutManager.HORIZONTAL)
        appRecycler!!.layoutManager = mLayoutManager
        //2。设置滚动辅助工具
        val pageSnapHelper = PagerGridSnapHelper()
        pageSnapHelper.attachToRecyclerView(appRecycler)
        appRecycler!!.adapter = mAppAdapter

        //设置点
        val manager = LinearLayoutManager(getActivity())
        manager.orientation = RecyclerView.HORIZONTAL
        pointRecycler!!.layoutManager = manager
        pointRecycler!!.adapter = mPointAdapter
    }

    override fun initListener() {
        EventBus.getDefault().register(this)

        mAppAdapter?.setItemOnClickListener(this@AppFragment)
        mAppAdapter?.setOnItemDeleteListener(this@AppFragment)
        mPointAdapter!!.setItemOnClickListener(object : BaseAdapter.BaseItemListener<Int?>{
            override fun onItemClickListener(v: View?, data: Int?, position: Int) {
                if (index < position) {
                    mLayoutManager!!.smoothNextPage()
                } else if (index > position) {
                    mLayoutManager!!.smoothPrePage()
                }
                index = position
            }
        })
        // 设置页面变化监听器
        mLayoutManager!!.setPageListener(this)
        appRecycler!!.setOnTouchListener { v: View, event: MotionEvent ->
            if (event.action == MotionEvent.ACTION_DOWN) {
                scrollX = event.x
                scrollY = event.y
            }
            if (event.action == MotionEvent.ACTION_UP) {
                if (v.id != 0 && Math.abs(scrollX - event.x) <= 5 && Math.abs(
                        scrollY - event.y
                    ) <= 5
                ) {
                    //recyclerView空白处点击事件
                    if (mAppAdapter?.getDeleteShow() == true) {
                        mAppAdapter?.setDeleteShow(false)
                    }
                }
            }
            false
        }

        systemViewModel?.appModeListLiveData?.observe(this@AppFragment){
            try {
                if (it!!.size == 0) {
                    //如果没有系统应用，或下载的应用，则自动取消卸载按钮
                    mAppAdapter?.setDeleteShow(false)
                }
                mAppAdapter?.setData(it)

                //计算有多少页
                val page = Math.ceil((it!!.size * 1.0f / (rows * columns)).toDouble()).toInt()
                val integerList: MutableList<Int> =
                    ArrayList()
                for (i in 0 until page) {
                    integerList.add(i)
                }
                LogUtils.i(TAG, " APP自带+数据库+系统应用：  " + it!!.size + "  integerList: " + integerList.size)
                if (integerList.size <= 1) {
                    pointRecycler!!.visibility = View.GONE
                } else {
                    pointRecycler!!.visibility = View.VISIBLE
                }
                mPointAdapter?.setData(integerList)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        binding?.igClose?.setOnClickListener {
            activity?.let { it1 -> FragmentOpenManager.getInstance().closeFragment(it1) }
        }
        binding?.rlContent?.setOnClickListener {  }
        binding?.rlOutsideView?.setOnClickListener {
            activity?.let { it1 -> FragmentOpenManager.getInstance().closeFragment(it1) }
        }
    }

    override fun onClick(v: View?) {}
    override fun onResume() {
        super.onResume()
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun refreshAppData(event: AppDeleteEvent) {
        //卸载成功回调，删除数据库
        deleteSuccess(event.isDeleteSuccess)
        mHandler.removeCallbacks(mRunnable)
        if (event.isDeleteSuccess) {
            ToastUtils.showToast(getString(R.string.deleteSuccess))
        } else {
            ToastUtils.showToast(getString(R.string.deleteError))
        }
    }

    private fun deleteSuccess(success: Boolean) {
        if (ll_delete_ing != null) {
            ll_delete_ing!!.visibility = View.GONE
        }

        if (mDeleteAppMode != null) {
            if (success && !TextUtils.isEmpty(mDeleteAppMode!!.packageName)) {
                MainApplication.getContext().getAppDataBaseInstance().AppDataRoomDao()
                    .queryByData(mDeleteAppMode!!.packageName)
                    .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(Consumer<AppDataRoomInfo?> { appDataRoomInfos ->
                        if (appDataRoomInfos != null) {
                            val completable: Completable = MainApplication.getContext().getAppDataBaseInstance().AppDataRoomDao().delete(appDataRoomInfos)
                            CompositeDisposable().add(completable.subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).subscribe()
                            ) //删除数据
                        }
                    }, Consumer<Throwable?> { })
            }
            mDeleteAppMode = null
            IsUnloading = false
            mAppAdapter?.setDeleting(false)
            systemViewModel?.loadAppModeList()
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    fun refreshApp(event: InstalledEvent) {
        //安装成功回调，刷新
        if (event.isInstalledSuccess) {
            systemViewModel?.loadAppModeList()
        }
    }




    /**
     * 卸载APP
     *
     * @param mode
     * @param position
     */
    @SuppressLint("CheckResult")
    override fun onDeleteApp(mode: AppMode, position: Int) {
        mDeleteAppMode = mode
        val deleteDialog = DeleteDialog()
        var appName = ""
        if (mode.info != null) {
            appName = mode.info.name
            mPackageName = mode.info.packageName
        } else if (!mode.packageName.isNullOrEmpty()) {
            appName = mode.label
            mPackageName = mode.packageName
        } else if (!TextUtils.isEmpty(mode.name)) {
            appName = mode.name
        }
        val format: String = String.format(getString(R.string.app_delete), appName)
        deleteDialog.setString(format)
        deleteDialog.setOnDeleteDialogListener(object : DeleteDialog.OnDeleteDialogListener{
            override fun delete() {
                if (TextUtils.isEmpty(mPackageName) && mode.icon != null) {
                    noApp()
                    return
                }
                deleteDialog.dismiss()
                IsUnloading = true
                if (ll_delete_ing != null) {
                    ll_delete_ing!!.visibility = View.VISIBLE
                }
                mAppAdapter?.setDeleting(true)
                if (mode.icon == null) {
                    DefaultMenuUtil.delete_menu(mode.id)
                    deleteSuccess(true)
                } else {
                    //静默卸载
                    uninstallPackage(mPackageName)
                }
            }
        })
        fragmentManager?.let { deleteDialog.show(it, "") }
    }

    /**
     * @param packageName 应用包名
     * 静默卸载
     */
    private fun uninstallPackage(packageName: String) {
        try {
            time = 0
            mHandler.post(mRunnable)
            LogUtils.i(TAG, "正在卸载：$packageName")
            val intent = Intent(context, context?.javaClass)
            val sender = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
            val mPackageInstaller: PackageInstaller = context?.packageManager!!.packageInstaller
            mPackageInstaller.uninstall(packageName, sender.intentSender)
        } catch (e: Exception) {
            e.printStackTrace()
            //应用不存在
            noApp()
        }
    }

    private val mRunnable: Runnable = object : Runnable {
        override fun run() {
            if (time >= 60) {
                time = 0
                var isUninstall = true
                mHandler.removeCallbacks(this)
                if (context == null) {
                    return
                }
                //60秒安装不成功判断APP包名是否存在，不存在则安装失败，郎国有时候接收不到安装成功回调
                val pm: PackageManager = context!!.packageManager
                val packages = pm.getInstalledPackages(0)
                for (packageInfo in packages) {
                    // 判断系统/非系统应用
                    if (packageInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM == 0) {
                        LogUtils.e("installedAppListIsNotSyatem", packageInfo.applicationInfo.packageName)
                        if (packageInfo.applicationInfo.packageName == mPackageName) {
                            isUninstall = false
                            break
                        }
                    } else {
                        if (packageInfo.applicationInfo.packageName == mPackageName && packageInfo.applicationInfo.packageName == "com.google.android.youtube" ||
                            packageInfo.applicationInfo.packageName == mPackageName && packageInfo.applicationInfo.packageName == "com.spotify.music"
                        ) {
                            isUninstall = false
                            break
                        }
                    }
                }
                //无论卸载是否成功，都要刷新列表
                deleteSuccess(isUninstall)
            } else {
                mHandler.postDelayed(this, 1000)
                time += 1
            }
        }
    }

    private fun noApp() {
        ToastUtils.showToast(getString(R.string.no_app))
        if (ll_delete_ing != null) {
            ll_delete_ing!!.visibility = View.GONE
        }
        if (mDeleteAppMode != null && mDeleteAppMode!!.info != null) {
            val completable: Completable =
                MainApplication.getContext().getAppDataBaseInstance().AppDataRoomDao()
                    .delete(mDeleteAppMode!!.info)
            CompositeDisposable().add(
                completable.subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io()).subscribe()
            ) //删除数据
            mDeleteAppMode = null
            IsUnloading = false
            mAppAdapter?.setDeleting(false)
            systemViewModel?.loadAppModeList()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    }

    override fun onPageSizeChanged(pageSize: Int) {
        //页面总数量变化

    }

    override fun onPageSelect(pageIndex: Int) {
        //页面被选中
        index = pageIndex
        mPointAdapter?.setCurrentIndex(pageIndex)
        Log.e("onPageSelect", "" + pageIndex)
    }

    override fun onDestroyView() {
        EventBus.getDefault().unregister(this)
        IsUnloading = false
        mHandler.removeCallbacks(mRunnable)
        super.onDestroyView()
    }

    override fun setMenuVisibility(menuVisible: Boolean) {
        super.setMenuVisibility(menuVisible)
        if(menuVisible){
            try {
                index = 0
                mAppAdapter?.setDeleteShow(false)
                mLayoutManager!!.scrollToPosition(index)
                mPointAdapter?.setCurrentIndex(index)
            }catch (e : Exception ){
                e.printStackTrace()
            }

        }
    }

    override fun onItemClickListener(v: View?, data: AppMode, position: Int) {
        //打开对应的菜单功能
        val appMode: AppMode = data as AppMode
        openMenu(appMode, activity)
        if (!TextUtils.isEmpty(appMode.name) && appMode.id === ID_MESSAGE) {
            Handler().postDelayed({
                MirrorDataStorage.instance().storeInt(Constants.unread_messages, 0)
                mAppAdapter?.notifyDataSetChanged()
            }, 200)
        }
    }

    companion object {
        var IsUnloading = false //是否正在卸载

        //菜单功能ID
        const val ID_APP_STORE = 0
        const val ID_MESSAGE = 1
        const val ID_HEALTH = 2
        const val ID_SETTING = 4
        const val ID_MUSIC = 5
        const val ID_VIDEO = 6
        const val ID_FLIQLO = 7
        const val ID_BRUSH = 8
        const val ID_FM = 9
        /**
         * 打开对应的菜单功能
         *
         * @param appMode
         * @param activity
         */
        fun openMenu(appMode: AppMode, activity: FragmentActivity?) {
            if (!TextUtils.isEmpty(appMode.name)) {
                //打开系统自带功能
                when (appMode.id) {
                    ID_HEALTH -> {
                        activity?.let { FragmentOpenManager.getInstance().addFragment(it,HealthFragment()) }
                    }
                    ID_SETTING -> {
                        activity?.let { FragmentOpenManager.getInstance().addFragment(it,WiFiFragment()) }
                    }
                    ID_FM ->{
                        AppUtil.openOtherApp(MainApplication.getContext(),appMode.packageName)
                    }
                    ID_MUSIC -> {
                        AppUtil.openOtherApp(MainApplication.getContext(),appMode.packageName)
                    }
                    ID_VIDEO -> {
                        AppUtil.openOtherApp(MainApplication.getContext(),appMode.packageName)
                    }
                    ID_FLIQLO -> {
                        ToastUtils.showToast("敬请期待")
                    }
                    ID_MESSAGE -> {
                        ToastUtils.showToast("敬请期待")
                    }
                    ID_BRUSH -> {
                        ToastUtils.showToast("敬请期待")
                    }
                }
            } else if (appMode.info != null) {
                //打开下载的第三方应用
                AppUtil.openOtherApp(
                    MainApplication.getContext(),
                    appMode.info.packageName
                )
                MirrorDataStorage.instance().storeString(Constants.current_application, appMode.info.packageName)
                LogUtils.i("openOtherApp", appMode.info.name + "   " + appMode.info.packageName
                )
                AppUtil.killOtherApp(MainApplication.getContext(), appMode.info.packageName)
            } else if (!TextUtils.isEmpty(appMode.packageName)) {
                //打开获取系统的第三方应用
                AppUtil.openOtherApp(MainApplication.getContext(), appMode.packageName)
                MirrorDataStorage.instance()
                    .storeString(Constants.current_application, appMode.packageName)
                LogUtils.i("openOtherApp", appMode.packageName)
                AppUtil.killOtherApp(MainApplication.getContext(), appMode.packageName)
            }
        }

        fun getMenuName(context: Context, id: Int): String {
            return when (id) {
                ID_APP_STORE -> context.getString(R.string.app_store)
                ID_HEALTH -> context.getString(R.string.main_health)
                ID_SETTING -> context.getString(R.string.app_setting)
                ID_MUSIC -> context.getString(R.string.main_music)
                ID_VIDEO -> context.getString(R.string.main_video)
                ID_FM -> context.getString(R.string.main_fm)
                ID_FLIQLO -> context.getString(R.string.main_fliqlo)
                ID_MESSAGE -> context.getString(R.string.main_message)
                ID_BRUSH -> context.getString(R.string.main_brush)
                else -> ""
            }
        }
    }

}